package core.sceneManager.sceneSection.scene3DSection
{
	import core.MainManager;
	import core.sceneManager.IScene;
	import core.sceneManager.SceneManager;
	import core.sceneManager.sceneSection.ISceneSection;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;
	
	import memory.MemoryRecovery;
	
	import org.papervision3d.core.proto.SceneObject3D;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.view.Viewport3D;
	
	import pv3d.cameras.RotateableFreeCamera3D;
	
	import utils.XmlTranslater;

	public class Scene3D extends EventDispatcher implements IScene
	{
		private var dataBase:XML;                         //3D场景的数据库
		private var renderer:BasicRenderEngine;           //3D场景的渲染器
		private var container:SceneObject3D;              //3D场景模块的容器
		private var camera:RotateableFreeCamera3D;        //3D场景的镜头
		private var viewport:Viewport3D;                  //3D场景的视窗
		private var index:int=-1;
		private var isRendering:Boolean=false;            //是否正在渲染中
		public function Scene3D(target:IEventDispatcher=null)
		{
			super(target);
		}
		/**
		 * 创建所有的模块
		 */ 
		public function createSections(xml:XML):void
		{
			if(xml==null || xml.Section==null || xml.Section.length==0)
			{
				this.dispatchEvent(new Event(Event.COMPLETE));             //如果XML不存在或者没有需要创建的模块,那么直接抛出创建完毕的事件
			}
			this.dataBase=xml;                                             //存储3D场景的数据库
			create3D();                                                    //创建基本的3D场景
			for each(var item:XML in xml.attributes())        
			{
				var key:String=item.name();
				this[key]=item.toString();
			}
			createSection();//创建模块
		}
		private function createSection():void
		{
			index++;
			if(index==dataBase.Section.length())
			{
				resume();                                         //开始渲染
				this.dispatchEvent(new Event(Event.COMPLETE));    //抛出完毕的事件
			}else
			{
				var sectionXml:XML=dataBase.Section[index];
				var type:String=sectionXml.@type;     //模块的类型，肯定要了
				var sectionName:String=sectionXml.@sectionName;    //模块的名字，用来区别模块
				var section:ISceneSection;
				var container:*;
				switch(type)
				{
					case "sphere":section=new CustomSphere();container=this.container;break;
					case "sp":section=new StaticPlane;container=this.container;break;
					case "ap":section=new AnimatePlane();container=this.container;break;
					case "psa":section=new Pv3dShpereAddon();container=this.container;break;
				}
				SceneManager.sections.addSection(type,sectionName,XmlTranslater.translateBoolean(sectionXml.@autoRefresh),section);//存储模块
				section.excute(sectionXml,container);
				section.start();
				handleWaitForComplete(sectionXml.@waitForComplete,section);
			}
		}
		//设置模块的waitForComplete属性,无需等待的话，直接加载新模块，要等待的话就等待模块加载完毕
		private function handleWaitForComplete(waitForComplete:String,section:ISceneSection):void
		{
			if(waitForComplete=="" || waitForComplete==null || waitForComplete=="0")
			{
				createSection();
			}else
			{
				section.addEventListener(Event.COMPLETE,on_section_created);
			}
		}
		//模块创建完毕
		private function on_section_created(e:Event):void
		{
			this.createSection();//继续创建
			MemoryRecovery.getInstance().gcFun(e.currentTarget,Event.COMPLETE,on_section_created);
		}
		private function create3D():void
		{
			renderer = new BasicRenderEngine();
			container = new SceneObject3D();
			viewport = new Viewport3D(900, 480, false, false);
			viewport.interactive=true;
			MainManager.getInstance().getContainer(0).addChild(viewport);//3d放在第0层
			createCamera();
		}
		private function createCamera():void
		{
			camera = new RotateableFreeCamera3D();
			camera.focus=25;
			//创建镜头
			var i:int=0;
			var fromScene:int =-1;
			for(i=0;i<dataBase.Camera.length();i++)//匹配场景ID
			{
				if(int(dataBase.Camera[i].@fromScene)==SceneManager.getInstance().currentSceneId)
				{
					fromScene=dataBase.Camera[i].@formScene;
				}
			}
			if(fromScene!=-1)
			{
				var temp:XML=dataBase.Camera[i-1];
				for each(var item:XML in temp.attributes())      //配置镜头的属性  
				{
					try
					{
						var key:String=item.name();
						camera[key]=item.toString();
					}catch(e:Error){}
				}
			}
			camera.z = 1;
		}
		//鼠标进入就开始渲染
		private function on_mouse_over(e:MouseEvent):void
		{
			resume();
		}
		//鼠标离开就停止渲染
		private function on_mouse_out(e:MouseEvent):void
		{
			pause();
		}
		//渲染
		private function draw(e:Event):void
		{
			renderer.renderScene(container, camera, viewport);
		}
		/**
		 * 继续播放三维场景
		 */ 
		public function resume():void
		{
			if(!isRendering)
			{
				MainManager.getInstance().stage.addEventListener(Event.ENTER_FRAME,draw);
				isRendering=true;
			}
		}
		/**
		 * 暂停三维场景
		 */ 
		public function pause():void
		{
			if(isRendering)
			{
				MemoryRecovery.getInstance().gcFun(MainManager.getInstance().stage,Event.ENTER_FRAME,draw);
				isRendering=false;
			}
		}
		public function disposeEvent():void
		{
			MemoryRecovery.getInstance().gcFun(MainManager.getInstance().stage,Event.ENTER_FRAME,draw);
		}
		/**
		 * 回收内存
		 */ 
		public function dispose():void
		{
			dataBase=null;
			if(camera!=null) camera.dispose();
			camera=null;
			if(renderer!=null) renderer.destroy();
			renderer=null;
			if(container!=null) container.dispose();
			container=null;
			if(viewport!=null)
			{
				viewport.destroy();
				if(viewport.parent!=null) viewport.parent.removeChild(viewport);
			}
		}
		////////////////////////////////下面声明属性给XML调用//////////////////////////
		private function set cameraRotationX(val:Number):void
		{
			camera.rotationX=val;
		}
		private function set cameraRotationY(val:Number):void
		{
			camera.rotationY=val;
		}
		private function set cameraRotationZ(val:Number):void
		{
			camera.rotationZ=val;
		}
		private function set cameraFocus(val:Number):void
		{
			camera.focus=val;
		}
		private function set cameraX(val:Number):void
		{
			camera.x=val;
		}
		private function set cameraY(val:Number):void
		{
			camera.y=val;
		}
		private function set cameraZ(val:Number):void
		{
			camera.z=val;
		}
		private function set viewportX(val:Number):void
		{
			viewport.x=val;
		}
		private function set viewportY(val:Number):void
		{
			viewport.y=val;
		}
		//////////////////////////////下面的可以不用看/////////////////////////////
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			super.addEventListener(type,listener,useCapture,priority,useWeakReference);
		}
		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			super.removeEventListener(type,listener,useCapture);
		}
	}
}